// 语言国际化 数据仓库
import { observable, computed, action } from 'mobx';
import fmtMessage from 'format-message';

// 默认语言包 同步引入
import zh from '@/locales/zh-CN';

// 语言设置缓存key
const langStorageKey = 'originLanguage_';

// 支持的语言配置 优先级按先后
const config = [
  {
    lang: 'zh-CN',
    text: '中文',
    // 全局语言包
    package: zh,
    // 组件自定义语言包缓存
    messages: {}
  },
  {
    lang: 'en-US',
    text: 'English',
    // 全局语言包
    package: () => import(/* webpackChunkName: "en" */ '@/locales/en-US'),
    // 组件自定义语言包缓存
    messages: {}
  }
];

// 获取当前支持的语言key
const getSuportLang = lang => {
  const index = config.indexOf(l => l.lang === lang);
  if (index > -1) {
    return lang;
  }
  if (/^zh/i.test(lang)) {
    return 'zh-CN';
  }
  return 'en-US';
};

// 获取语言设置
const LanguageString = () =>
  localStorage.getItem(langStorageKey) ||
  (navigator.languages && navigator.languages[0]) ||
  navigator.language ||
  navigator.userLanguage;

class Language {
  // 原始语言设置
  @observable originLang = '';

  // 语言包加载状态
  @observable loading = false;

  // 默认语言包数据
  @observable defaultLocale = {};

  // antd语言包
  @observable antd = {};

  // 自定义语言包 全局+组件
  @observable messages = {};

  constructor() {
    this.originLang = LanguageString();
    const defaultLang = config[0];
    // 默认语言包
    const locale = defaultLang.package;
    this.setLocaleData(locale);
    // 判断 默认语言与设置语言是否一致
    if (this.lang !== defaultLang.lang) {
      // 加载对应语言包
      this.switchLocale(this.lang);
    }
  }

  // 转换为支持的语言
  @computed get lang() {
    return getSuportLang(this.originLang);
  }

  // moment 语言key
  @computed get momentLang() {
    if (this.lang === 'zh-CN') {
      return 'zh-cn';
    }
    return 'en-gb';
  }

  // react intl 语言key
  @computed get intlLang() {
    if (this.lang === 'zh-CN') {
      return 'zh';
    }
    return 'en';
  }

  // support 语言 列表
  @computed static suportLanguages() {
    return config.map(m => ({ lang: m.lang, text: m.text }));
  }

  // 设置loading
  @action setLoading(loading = false) {
    this.loading = loading;
  }

  // 设置originLang
  @action setOrginLang(lang) {
    this.originLang = lang;
  }

  // 切换语言包
  @action setLang(lang) {
    const suportLang = getSuportLang(lang);
    // 加载对应语言包
    this.switchLocale(suportLang).then(() => {
      this.setOrginLang(suportLang);
      // 缓存语言设置
      localStorage.setItem(langStorageKey, suportLang);
    });
  }

  // 设置语言包数据
  @action setLocaleData(locale, cacheMessage = {}) {
    this.defaultLocale = locale.defaultLocale;
    this.antd = locale.antd;
    // 合并缓存 及 全局语言包
    this.messages = Object.assign({}, locale.messages, cacheMessage);
  }

  // 加载语言包 支持 同步和异步加载
  @action switchLocale(locale = config[0].lang) {
    const localLang = config.find(m => m.lang === locale);
    this.setLoading(true);
    return new Promise((resolve, reject) => {
      if (!localLang) {
        reject(new Error(`Do not support : ${locale} !`));
      }
      const pkg = localLang.package;
      if (typeof pkg === 'function') {
        pkg()
          .then(res => {
            const langLocale = res.default || res;
            this.setLocaleData(langLocale, localLang.messages);
            resolve();
          })
          .catch(e => {
            console.log(e);
            reject(e);
          })
          .finally(() => {
            this.setLoading(false);
          });
      } else {
        this.setLoading(false);
        this.setLocaleData(pkg, localLang.messages);
        resolve();
      }
    });
  }

  // 合并组件自定义语言包
  @action addLocale(componentMessages = {}) {
    if (Object.keys(componentMessages).length === 0) return;
    // 当前语言设置
    config.forEach((m, index) => {
      const childLang = componentMessages[m.lang];
      if (childLang && Object.keys(childLang).length > 0) {
        const oldMsg = m.messages;
        // 合并到 缓存
        config[index].messages = Object.assign({}, oldMsg, childLang);
        // 合并到 messages
        if (m.lang === this.lang) {
          this.messages = Object.assign({}, this.messages, childLang);
        }
      }
    });
  }

  //
  @action formatMessage(id, params = {}) {
    const templete = this.messages[id];
    if (!templete) {
      throw new Error(`language ${this.lang} key ${id} not found!`);
    }
    return fmtMessage(templete, params);
  }
}
export default new Language();

/*
浏览器languages大全：
"af", "sq", "ar-SA", "ar-IQ", "ar-EG", "ar-LY", "ar-DZ", "ar-MA", "ar-TN", "ar-OM",
    "ar-YE", "ar-SY", "ar-JO", "ar-LB", "ar-KW", "ar-AE", "ar-BH", "ar-QA", "eu", "bg",
    "be", "ca", "zh-TW", "zh-CN", "zh-HK", "zh-SG", "hr", "cs", "da", "nl", "nl-BE", "en",
    "en-US", "en-EG", "en-AU", "en-GB", "en-CA", "en-NZ", "en-IE", "en-ZA", "en-JM",
    "en-BZ", "en-TT", "et", "fo", "fa", "fi", "fr", "fr-BE", "fr-CA", "fr-CH", "fr-LU",
    "gd", "gd-IE", "de", "de-CH", "de-AT", "de-LU", "de-LI", "el", "he", "hi", "hu",
    "is", "id", "it", "it-CH", "ja", "ko", "lv", "lt", "mk", "mt", "no", "pl",
    "pt-BR", "pt", "rm", "ro", "ro-MO", "ru", "ru-MI", "sz", "sr", "sk", "sl", "sb",
    "es", "es-AR", "es-GT", "es-CR", "es-PA", "es-DO", "es-MX", "es-VE", "es-CO",
    "es-PE", "es-EC", "es-CL", "es-UY", "es-PY", "es-BO", "es-SV", "es-HN", "es-NI",
"es-PR", "sx", "sv", "sv-FI", "th", "ts", "tn", "tr", "uk", "ur", "ve", "vi", "xh",
"ji", "zu"]; */
